package org.mame.builders;

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.util.Properties;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.mame.util.XMLProcessor;

/**
 * UpdateROMConfig is the second generation utility to search a given location for game files 
 * and create a configuration file that can be read by the HyperSpin frontend to list playable games
 * 
 * This version has the ability to update the existing file rather than overwrite it, allowing for 
 * additional data to be safely entered without fear of overwriting it, such as publisher, year, genre, etc.
 * 
 * @author Bill
 * @version 1.0
 */
public class UpdateROMConfig {
	private static Logger log;
	private static Properties props;
	private static Document doc;
	private static Element menu;
	
	// XML Constants
	private static final String XML_ROOT = "menu";
	private static final String XML_HEADER = "header";
	private static final String XML_LIST_NAME = "listname";
	private static final String XML_LIST_UPDATE = "lastlistupdate";
	private static final String XML_LIST_VERSION = "listversion";
	private static final String XML_EXPORTER_VERSION = "exporterversion";
	
	// Error codes
	private static final int ERROR_DOM_DOC_NULL = 1;
	
	static{
		log   = LogManager.getLogger(UpdateROMConfig.class.getName());
		
		props = new Properties();
		doc   = null;
	}
	
	/*
	 * Utility method used for testing purposes only.  Wil not be used in the functional version
	 */
	public static void main(String[] args){
		//int result = updateConfigFile("", "C:\\Users\\MAME\\Downloads\\HyperSpin\\Databases\\Atari 2600\\Atari 2600.xml", true);
		int result = updateConfigFile(null, null, true);
		
		System.out.println("Results: " + result);
	}
	
	/**
	 * Updates the existing config file, or creates a new one if necessary, with the current
	 * list of game files for the given system
	 * 
	 * @param propertyFile- property file showing where to look for games, media, hyperspin, etc
	 * @param configFile- The location of the existing configuration or the location to create the new configuration
	 * 
	 * @return 0 if successful, >0 otherwise
	 */
	public static int updateConfigFile(String propertyFile, String configFile){
		log.debug("Defaulting test output to no, sending to work method");
		return updateConfigFile(propertyFile, configFile, false);
	}
	
	/**
	 * Updates the existing config file, or creates a new one if necessary, with the current
	 * list of game files for the given system
	 * 
	 * @param propertyFile- property file showing where to look for games, media, hyperspin, etc
	 * @param configFile- The location of the existing configuration or the location to create the new configuration
	 * @param testOutput- true to open the resulting file using the OS' default program, false to not open it
	 * 
	 * @return 0 if successful, >0 otherwise
	 */
	public static int updateConfigFile(String propertyFile, String configFile, boolean testOutput){
		log.debug("Entering updateConfigFile(String, String, boolean)");
		// If the config file given is blank create a new one
		if(configFile == null || "".equals(configFile)){
			log.info("No current config file given, creating a new one");
			doc = XMLProcessor.createNewDomDoc();
			initializeDoc();
		// Otherwise send the given file to be loaded into a DOMDocument
		}else{
			log.debug("Loading " + configFile);
			doc = XMLProcessor.importDoc(configFile);
		}
		
		// Either way at this point the doc had better not be null or there's gonna be trouble
		if(doc == null){
			log.error("Error: DOMDocument recieved is null after loading");
			return ERROR_DOM_DOC_NULL;
		}
		
		if(testOutput){
			File tmp = new File(configFile);
			XMLProcessor.writeDoc(tmp, doc);
			try {
				Desktop.getDesktop().open(tmp);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return 0;
	}

	/*
	 * Initializes a blank DOM Document, creating the header elements requires by HyperSpin
	 */
	@SuppressWarnings("unused")
	private static void initializeDoc() {
		// Create the header tags that are common to all hyperspin configs
		menu = doc.addElement(XML_ROOT);
		Element header = menu.addElement(XML_HEADER);
		Element listName = header.addElement(XML_LIST_NAME);
		listName.addText("List Test");
		Element listUpdated = header.addElement(XML_LIST_UPDATE);
		Element listVersion = header.addElement(XML_LIST_VERSION);
		Element exporterVersion = header.addElement(XML_EXPORTER_VERSION);
	}
	
}
